package com.sqlcheck.service.impl;

import com.sqlcheck.common.enums.DatabaseType;
import com.sqlcheck.entity.CompatibilityRule;
import com.sqlcheck.entity.LLMPromptTemplate;
import com.sqlcheck.service.PromptGeneratorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class PromptGeneratorServiceImpl implements PromptGeneratorService {

    private static final String PROMPT_TEMPLATE_V2_PATH = "prompt/sqlcheck_prompt_v2.md";

    @Override
    public String buildPrompt(DatabaseType sourceDbType, DatabaseType targetDbType,
            String sql, List<CompatibilityRule> rules) {
        log.info("构建结构化提示词 - 源数据库: {}, 目标数据库: {}, 规则数量: {}",
                sourceDbType, targetDbType, rules != null ? rules.size() : 0);

        try {
            // 读取新的prompt模板文件
            String template = loadPromptTemplate();

            // 构建变量映射
            Map<String, Object> variables = new HashMap<>();
            variables.put("source_database", sourceDbType.toString());
            variables.put("target_database", targetDbType.toString());
            variables.put("migration_rules", formatRulesForPrompt(rules));
            variables.put("numbered_sql_statements", formatSqlForPrompt(sql));

            // 渲染模板
            String renderedPrompt = renderTemplate(template, variables);

            log.info("生成的统一分析提示词长度: {} 字符", renderedPrompt.length());
            return renderedPrompt;

        } catch (Exception e) {
            log.error("读取prompt模板失败，使用备用生成逻辑", e);
            return buildFallbackPrompt(sourceDbType, targetDbType, sql, rules);
        }
    }

    /**
     * 加载prompt模板文件
     */
    private String loadPromptTemplate() throws IOException {
        ClassPathResource resource = new ClassPathResource(PROMPT_TEMPLATE_V2_PATH);
        return StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
    }

    /**
     * 格式化规则信息用于prompt（保留规则详情，删除规则ID）
     */
    private String formatRulesForPrompt(List<CompatibilityRule> rules) {
        if (rules == null || rules.isEmpty()) {
            return "当前没有配置具体的迁移规则，请按照数据库最佳实践进行优化。";
        }

        StringBuilder rulesText = new StringBuilder();

        for (int i = 0; i < rules.size(); i++) {
            CompatibilityRule rule = rules.get(i);
            rulesText.append("\n**规则编号**: ").append(rule.getRuleId())
                    .append("\n**规则名称**: ").append(rule.getRuleName())
                    .append("\n**分类**: ").append(rule.getCategory())
                    .append("\n**严重程度**: ").append(rule.getSeverity())
                    .append("\n**描述**: ").append(rule.getDescription())
                    .append("\n**建议**: ").append(rule.getSuggestion());

            if (rule.getExampleSql() != null && !rule.getExampleSql().trim().isEmpty()) {
                rulesText.append("\n**示例SQL**: ").append(rule.getExampleSql());
            }
            if (rule.getSuggestedSql() != null && !rule.getSuggestedSql().trim().isEmpty()) {
                rulesText.append("\n**建议SQL**: ").append(rule.getSuggestedSql());
            }
            rulesText.append("\n");
        }

        return rulesText.toString();
    }

    /**
     * 格式化SQL语句用于prompt（分配编号）
     */
    private String formatSqlForPrompt(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return "";
        }

        // 检查是否是批量分析格式（包含特殊标识）
        if (sql.contains("-- BATCH SQL ANALYSIS REQUEST --")) {
            log.debug("检测到批量分析格式，直接使用已格式化的SQL内容");
            return sql; // 直接返回已经格式化的批量SQL内容
        }

        // 原有的单语句分割逻辑（向后兼容）
        String[] statements = sql.split(";");
        StringBuilder numberedSql = new StringBuilder();

        int statementNumber = 1;
        for (String statement : statements) {
            String trimmed = statement.trim();
            if (!trimmed.isEmpty()) {
                numberedSql.append("\n**语句#").append(statementNumber).append("**:\n")
                        .append(trimmed)
                        .append(trimmed.endsWith(";") ? "" : ";")
                        .append("\n");
                statementNumber++;
            }
        }

        return numberedSql.toString();
    }

    /**
     * 备用prompt生成逻辑（当模板文件读取失败时使用）
     */
    private String buildFallbackPrompt(DatabaseType sourceDbType, DatabaseType targetDbType,
            String sql, List<CompatibilityRule> rules) {
        StringBuilder prompt = new StringBuilder();

        // ROLE (角色设定)
        prompt.append("# ROLE\n");
        prompt.append("你是一名精通数据库迁移的资深DBA，尤其擅长从 ").append(sourceDbType).append(" 迁移到 ").append(targetDbType).append("。");
        prompt.append("你的核心任务是分析用户提供的SQL，根据给定的兼容性规则，将其重写为兼容").append(targetDbType).append("的SQL，并清晰地解释每一个修改点。\n\n");

        // CONTEXT (上下文)
        prompt.append("# CONTEXT\n");
        prompt.append("- **源数据库 (Source Database)**: ").append(sourceDbType).append("\n");
        prompt.append("- **目标数据库 (Target Database)**: ").append(targetDbType).append("\n");
        prompt.append("- **任务目标**: 将\"原始SQL\"转换为完全兼容目标数据库的\"优化后SQL\"，并明确标识出变更。\n\n");

        // MIGRATION RULES (迁移规则)
        prompt.append("# MIGRATION RULES (迁移规则)\n");
        prompt.append("你必须严格遵守以下规则进行分析和优化。这些规则定义了从源数据库到目标数据库的不兼容点和修改建议：\n");
        prompt.append("---\n");

        if (rules != null && !rules.isEmpty()) {
            for (int i = 0; i < rules.size(); i++) {
                CompatibilityRule rule = rules.get(i);
                prompt.append("**规则 ").append(i + 1).append(" [").append(rule.getSeverity()).append("]**: ");
                prompt.append(rule.getRuleName()).append("\n");
                prompt.append("- **问题描述**: ").append(rule.getDescription()).append("\n");
                if (rule.getSuggestion() != null && !rule.getSuggestion().trim().isEmpty()) {
                    prompt.append("- **解决方案**: ").append(rule.getSuggestion()).append("\n");
                }
                if (rule.getExampleSql() != null && !rule.getExampleSql().trim().isEmpty()) {
                    prompt.append("- **修改前示例**: `").append(rule.getExampleSql()).append("`\n");
                }
                if (rule.getSuggestedSql() != null && !rule.getSuggestedSql().trim().isEmpty()) {
                    prompt.append("- **修改后示例**: `").append(rule.getSuggestedSql()).append("`\n");
                }
                prompt.append("\n");
            }
        } else {
            prompt.append("*当前没有配置具体的迁移规则，请按照数据库最佳实践进行优化*\n");
        }
        prompt.append("---\n\n");

        // INPUT SQL (原始SQL)
        prompt.append("# INPUT SQL (原始SQL)\n");
        prompt.append("```sql\n").append(sql).append("\n```\n\n");

        // 请求JSON格式输出
        prompt.append("# OUTPUT FORMAT\n");
        prompt.append("请严格按照JSON格式返回分析结果，包含statementAnalysis数组，每个语句包含originalStatement、optimizedStatement和issues。\n");

        String result = prompt.toString();
        log.info("生成的备用提示词长度: {} 字符", result.length());

        return result;
    }

    @Override
    public LLMPromptTemplate getPromptTemplate(String templateKey) {
        // 临时实现
        return null;
    }

    @Override
    public LLMPromptTemplate getBestTemplate(DatabaseType sourceDbType, DatabaseType targetDbType) {
        // 临时实现
        return null;
    }

    @Override
    public String renderTemplate(String template, Map<String, Object> variables) {
        String result = template;
        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            String placeholder = "{" + entry.getKey() + "}";
            String value = entry.getValue() != null ? entry.getValue().toString() : "";
            result = result.replace(placeholder, value);
        }
        return result;
    }

    @Override
    public boolean validateTemplate(String template) {
        return template != null && !template.trim().isEmpty();
    }

    @Override
    public void updateTemplateUsage(Long templateId, boolean success, Integer processingTime) {
        // 临时实现
        log.debug("更新模板使用统计: templateId={}, success={}", templateId, success);
    }
}